"use strict";

require("core-js/modules/es.object.keys.js");

require("core-js/modules/es.array.filter.js");

require("core-js/modules/es.object.get-own-property-descriptor.js");

require("core-js/modules/web.dom-collections.for-each.js");

require("core-js/modules/es.object.get-own-property-descriptors.js");

require("core-js/modules/es.array.from.js");

require("core-js/modules/es.array.slice.js");

require("core-js/modules/es.function.name.js");

require("core-js/modules/es.regexp.exec.js");

exports.__esModule = true;
exports.default = void 0;

require("core-js/modules/es.array.fill.js");

require("core-js/modules/es.array.iterator.js");

require("core-js/modules/es.map.js");

require("core-js/modules/es.object.to-string.js");

require("core-js/modules/es.string.iterator.js");

require("core-js/modules/web.dom-collections.iterator.js");

require("core-js/modules/es.array.includes.js");

require("core-js/modules/es.string.includes.js");

require("core-js/modules/es.array.concat.js");

require("core-js/modules/es.symbol.iterator.js");

require("core-js/modules/es.symbol.js");

require("core-js/modules/es.symbol.description.js");

var _types = require("./types");

var _constants = require("./constants");

var _array = require("./../../helpers/array");

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }

/**
 * Highlight class responsible for managing Walkontable Selection classes.
 *
 * With Highlight object you can manipulate four different highlight types:
 *  - `cell` can be added only to a single cell at a time and it defines currently selected cell;
 *  - `fill` can occur only once and its highlight defines selection of autofill functionality (managed by the plugin with the same name);
 *  - `areas` can be added to multiple cells at a time. This type highlights selected cell or multiple cells.
 *    The multiple cells have to be defined as an uninterrupted order (regular shape). Otherwise, the new layer of
 *    that type should be created to manage not-consecutive selection;
 *  - `header` can occur multiple times. This type is designed to highlight only headers. Like `area` type it
 *    can appear with multiple highlights (accessed under different level layers).
 *
 * @class Highlight
 * @util
 */
var Highlight = /*#__PURE__*/function (_Symbol$iterator) {
  function Highlight(options) {
    _classCallCheck(this, Highlight);

    /**
     * Options consumed by Highlight class and Walkontable Selection classes.
     *
     * @type {object}
     */
    this.options = options;
    /**
     * The property which describes which layer level of the visual selection will be modified.
     * This option is valid only for `area` and `header` highlight types which occurs multiple times on
     * the table (as a non-consecutive selection).
     *
     * An order of the layers is the same as the order of added new non-consecutive selections.
     *
     * @type {number}
     * @default 0
     */

    this.layerLevel = 0;
    /**
     * `cell` highlight object which describes attributes for the currently selected cell.
     * It can only occur only once on the table.
     *
     * @type {Selection}
     */

    this.cell = (0, _types.createHighlight)(_constants.CELL_TYPE, options);
    /**
     * `fill` highlight object which describes attributes for the borders for autofill functionality.
     * It can only occur only once on the table.
     *
     * @type {Selection}
     */

    this.fill = (0, _types.createHighlight)(_constants.FILL_TYPE, options);
    /**
     * Collection of the `area` highlights. That objects describes attributes for the borders and selection of
     * the multiple selected cells. It can occur multiple times on the table.
     *
     * @type {Map.<number, Selection>}
     */

    this.areas = new Map();
    /**
     * Collection of the `header` highlights. That objects describes attributes for the selection of
     * the multiple selected rows and columns in the table header. It can occur multiple times on the table.
     *
     * @type {Map.<number, Selection>}
     */

    this.headers = new Map();
    /**
     * Collection of the `active-header` highlights. That objects describes attributes for the selection of
     * the multiple selected rows and columns in the table header. The table headers which have selected all items in
     * a row will be marked as `active-header`.
     *
     * @type {Map.<number, Selection>}
     */

    this.activeHeaders = new Map();
    /**
     * Collection of the `custom-selection`, holder for example borders added through CustomBorders plugin.
     *
     * @type {Selection[]}
     */

    this.customSelections = [];
  }
  /**
   * Check if highlight cell rendering is disabled for specified highlight type.
   *
   * @param {string} highlightType Highlight type. Possible values are: `cell`, `area`, `fill` or `header`.
   * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
   * @returns {boolean}
   */


  _createClass(Highlight, [{
    key: "isEnabledFor",
    value: function isEnabledFor(highlightType, coords) {
      var type = highlightType; // Legacy compatibility.

      if (highlightType === _constants.CELL_TYPE) {
        type = 'current'; // One from settings for `disableVisualSelection` up to Handsontable 0.36/Handsontable Pro 1.16.0.
      }

      var disableHighlight = this.options.disabledCellSelection(coords.row, coords.col);

      if (typeof disableHighlight === 'string') {
        disableHighlight = [disableHighlight];
      }

      return disableHighlight === false || Array.isArray(disableHighlight) && !disableHighlight.includes(type);
    }
    /**
     * Set a new layer level to make access to the desire `area` and `header` highlights.
     *
     * @param {number} [level=0] Layer level to use.
     * @returns {Highlight}
     */

  }, {
    key: "useLayerLevel",
    value: function useLayerLevel() {
      var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
      this.layerLevel = level;
      return this;
    }
    /**
     * Get Walkontable Selection instance created for controlling highlight of the currently selected/edited cell.
     *
     * @returns {Selection}
     */

  }, {
    key: "getCell",
    value: function getCell() {
      return this.cell;
    }
    /**
     * Get Walkontable Selection instance created for controlling highlight of the autofill functionality.
     *
     * @returns {Selection}
     */

  }, {
    key: "getFill",
    value: function getFill() {
      return this.fill;
    }
    /**
     * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
     * of the multiple selected cells.
     *
     * @returns {Selection}
     */

  }, {
    key: "createOrGetArea",
    value: function createOrGetArea() {
      var layerLevel = this.layerLevel;
      var area;

      if (this.areas.has(layerLevel)) {
        area = this.areas.get(layerLevel);
      } else {
        area = (0, _types.createHighlight)(_constants.AREA_TYPE, _objectSpread({
          layerLevel: layerLevel
        }, this.options));
        this.areas.set(layerLevel, area);
      }

      return area;
    }
    /**
     * Get all Walkontable Selection instances which describes the state of the visual highlight of the cells.
     *
     * @returns {Selection[]}
     */

  }, {
    key: "getAreas",
    value: function getAreas() {
      return _toConsumableArray(this.areas.values());
    }
    /**
     * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
     * of the multiple selected header cells.
     *
     * @returns {Selection}
     */

  }, {
    key: "createOrGetHeader",
    value: function createOrGetHeader() {
      var layerLevel = this.layerLevel;
      var header;

      if (this.headers.has(layerLevel)) {
        header = this.headers.get(layerLevel);
      } else {
        header = (0, _types.createHighlight)(_constants.HEADER_TYPE, _objectSpread({}, this.options));
        this.headers.set(layerLevel, header);
      }

      return header;
    }
    /**
     * Get all Walkontable Selection instances which describes the state of the visual highlight of the headers.
     *
     * @returns {Selection[]}
     */

  }, {
    key: "getHeaders",
    value: function getHeaders() {
      return _toConsumableArray(this.headers.values());
    }
    /**
     * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
     * of the multiple selected active header cells.
     *
     * @returns {Selection}
     */

  }, {
    key: "createOrGetActiveHeader",
    value: function createOrGetActiveHeader() {
      var layerLevel = this.layerLevel;
      var header;

      if (this.activeHeaders.has(layerLevel)) {
        header = this.activeHeaders.get(layerLevel);
      } else {
        header = (0, _types.createHighlight)(_constants.ACTIVE_HEADER_TYPE, _objectSpread({}, this.options));
        this.activeHeaders.set(layerLevel, header);
      }

      return header;
    }
    /**
     * Get all Walkontable Selection instances which describes the state of the visual highlight of the active headers.
     *
     * @returns {Selection[]}
     */

  }, {
    key: "getActiveHeaders",
    value: function getActiveHeaders() {
      return _toConsumableArray(this.activeHeaders.values());
    }
    /**
     * Get Walkontable Selection instance created for controlling highlight of the custom selection functionality.
     *
     * @returns {Selection}
     */

  }, {
    key: "getCustomSelections",
    value: function getCustomSelections() {
      return _toConsumableArray(this.customSelections.values());
    }
    /**
     * Add selection to the custom selection instance. The new selection are added to the end of the selection collection.
     *
     * @param {object} selectionInstance The selection instance.
     */

  }, {
    key: "addCustomSelection",
    value: function addCustomSelection(selectionInstance) {
      this.customSelections.push((0, _types.createHighlight)(_constants.CUSTOM_SELECTION_TYPE, _objectSpread(_objectSpread({}, this.options), selectionInstance)));
    }
    /**
     * Perform cleaning visual highlights for the whole table.
     */

  }, {
    key: "clear",
    value: function clear() {
      this.cell.clear();
      this.fill.clear();
      (0, _array.arrayEach)(this.areas.values(), function (highlight) {
        return void highlight.clear();
      });
      (0, _array.arrayEach)(this.headers.values(), function (highlight) {
        return void highlight.clear();
      });
      (0, _array.arrayEach)(this.activeHeaders.values(), function (highlight) {
        return void highlight.clear();
      });
    }
    /**
     * This object can be iterate over using `for of` syntax or using internal `arrayEach` helper.
     *
     * @returns {Selection[]}
     */

  }, {
    key: _Symbol$iterator,
    value: function value() {
      return [this.cell, this.fill].concat(_toConsumableArray(this.areas.values()), _toConsumableArray(this.headers.values()), _toConsumableArray(this.activeHeaders.values()), _toConsumableArray(this.customSelections))[Symbol.iterator]();
    }
  }]);

  return Highlight;
}(Symbol.iterator);

var _default = Highlight;
exports.default = _default;